//
//  UsernamePasswordLoginViewModel.swift
//  User
//
//  Created by ET|冰琳 on 2017/1/13.
//  Copyright © 2017年 IB. All rights reserved.
//

import UIKit
import ReactiveSwift

public enum UsernamePasswordLoginError: Error {
    case usernameInvalide
    case passwordInvalide
    
    case error(msg: String)
}

open class UsernamePasswordLoginViewModel<Service: UsernamePasswordLoginService>: NSObject {
    
    open var username = MutableProperty<String?>(nil)
    open var password = MutableProperty<String?>(nil)
    
    open var usernameValide = MutableProperty(false)
    open var passwordValide = MutableProperty(false)
    
    open var usernameValidator: Validator?
    open var passwordValidator: Validator?

    private let service: Service
    
    open var loginAction: Action<(), Service.UsernamePasswordLoginResult, UsernamePasswordLoginError>!
    
    public init(service: Service) {
        self.service = service
        super.init()
        self.bind()
    }
    
    private func bind() {
        
        usernameValide <~ username.signal.map({
            let validator = self.usernameValidator ?? DefaultValidator()
            return validator.validate(txt: $0)
        })
        
        passwordValide <~ password.signal.map({
            let validator = self.passwordValidator ?? DefaultValidator()
            return validator.validate(txt: $0)
        })
        
        loginAction = Action {
            return self.login()
        }
    }
    
    private func login() -> SignalProducer<Service.UsernamePasswordLoginResult, UsernamePasswordLoginError> {
        
        guard self.usernameValide.value else {
            return SignalProducer(error: .usernameInvalide)
        }
        
        guard self.passwordValide.value else {
            return SignalProducer(error: .passwordInvalide)
        }
        
        return self.service.loginWith(username: self.username.value, password: self.password.value)
            .flatMapError({ (err) -> SignalProducer<Service.UsernamePasswordLoginResult, UsernamePasswordLoginError> in
                return SignalProducer(error: UsernamePasswordLoginError.error(msg: err.localizedDescription))
            })

    }
}
